package com.xiaoge.web;

import com.xiaoge.other.ZhangXiaoInitializer;
import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils;

import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
import java.lang.reflect.InvocationTargetException;
import java.util.Set;

/**
 * todo 自定义tomcat.start()后调用的类ZhangXiaoServletContainerInitializer, 来模拟一个springboot 达到0配置效果
 *
 * todo Tomcat调用ZhangXiaoServletContainerInitializer下的onStartup方法, 因为它实现了servlet3.0规范ServletContainerInitializer
 * 	 	而因为ZhangXiaoServletContainerInitializer类上加了@HandlesTypes(ZhangXiaoInitializer.class), 它获取找所有该类型的class
 * 	  	传入给webAppInitializerClasses, 其中就有我们自己写的MyInitializer, 然后掉它自己的onStartup方法
 *
 * todo 注意:classpath:META-INF/services下必须要有一个javax.servlet.ServletContainerInitializer文件名, 内容是它的实现类, 调用这个方法的前提是你要告诉tomcat这是个web项目(tomcat.addWebapp())
 *
 * @author <a href="mailto:1330137071@qq.com">Zhang Xiao</a>
 * @since
 */
@HandlesTypes(ZhangXiaoInitializer.class)
public class ZhangXiaoServletContainerInitializer implements ServletContainerInitializer {
	@Override
	public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {
		webAppInitializerClasses.forEach(webAppInitializerClass -> {
			try {
				ZhangXiaoInitializer initializer = (ZhangXiaoInitializer)ReflectionUtils.accessibleConstructor(webAppInitializerClass).newInstance();
				initializer.onStartup(servletContext);
			} catch (InstantiationException e) {
				throw new RuntimeException(e);
			} catch (IllegalAccessException e) {
				throw new RuntimeException(e);
			} catch (InvocationTargetException e) {
				throw new RuntimeException(e);
			} catch (NoSuchMethodException e) {
				throw new RuntimeException(e);
			} catch (ServletException e) {
				throw new RuntimeException(e);
			}
		});
	}
}
